package com.datalinkx.driver.dsdriver;

import com.datalinkx.common.utils.ConnectIdUtils;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

/**
 * @author 山顶洞人郑某
 * @className DsDriverFactory.java 数据源驱动工厂
 * @date 2025 03 16
 */
@Slf4j
public class DsDriverFactory {
    private DsDriverFactory() {

    }

    //前缀信息
    private static final String PACKAGE_PREFIX = "com.datalinkx.driver.dsdriver.";

    /**
     * 生成完整的类路径 如 "com.datalinkx.driver.dsdriver.mysql.driver.MysqlDriver"
     *
     * @param driverName
     * @return
     */
    private static String getDriverClass(String driverName) {
        //使用 ConnectIdUtils.toPascalCase(driverName) 将 driverName 转换为首字母大写的 Pascal 风格类名。
        //示例：如果 driverName 是 "mysql"，则类名为 "MysqlDriver".
        return PACKAGE_PREFIX + driverName.toLowerCase() + "driver" +
                "." + ConnectIdUtils.toPascalCase(driverName) + "Driver";
    }

    /**
     * 获取数据驱动器
     *
     * @param connectId 数据源必要信息通过压缩算法返回一个唯一字符串connectId，
     * @return 数据源驱动对象
     * @throws Exception
     */
    public static IDsDriver getDriver(String connectId) throws Exception {
        //解析压缩的connectId，获取数据源类型 比如“mysql”
        String dsType = ConnectIdUtils.getDsType(connectId);
        //获取驱动类路径
        String driverClassName = getDriverClass(dsType);
        //通过反射获取类对象
        Class<?> driverClass = Class.forName(driverClassName);
        Constructor<?> constructor = driverClass.getDeclaredConstructor(String.class);
        //通过反射创建对象
        return (IDsDriver) constructor.newInstance(connectId);
    }

    /**
     * 获取读取数据源驱动
     * @param connectId 数据源必要信息通过压缩算法返回一个唯一字符串connectId，
     * @return 数据源驱动对象
     * @throws Exception
     */
    public static IDsReader getDsReader(String connectId) throws Exception {
        try {
            try {
                return (IDsReader) getDriver(connectId);
            } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
                log.error("driver load error", e);
            }
        } catch (NoSuchMethodException e) {
            log.error("driver load error", e);
        }
        throw new Exception("can not initialize driver");
    }

    /**
     * 获取写入数据源驱动
     * @param connectId 获取读取数据源驱动
     * @return 数据源驱动对象
     * @throws Exception
     */
    public static IDsWriter getDsWriter(String connectId) throws Exception {
        try {
            try {
                return (IDsWriter) getDriver(connectId);
            } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
                log.error("driver load error", e);
            }
        } catch (NoSuchMethodException e) {
            log.error("driver load error", e);
        }

        throw new Exception("can not initialize driver");
    }
}

